package net.linku.config.record;

import org.springframework.context.ApplicationContext;
import org.springframework.context.expression.AnnotatedElementKey;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * 表达式管理
 *
 * @author: SilenceTian
 * @date: 2024/7/16 11:01
 * @version: 1.0
 */
public class LinkUExpressionEvaluator {

    private static final SpelExpressionParser PARSER = new SpelExpressionParser();
    private static final ParameterNameDiscoverer NAME_DISCOVERER = new DefaultParameterNameDiscoverer();

    public EvaluationContext createContext(Method method, Object[] args, Object target, Class<?> targetClass, ApplicationContext applicationContext) {
        StandardEvaluationContext context = new StandardEvaluationContext();
        context.setRootObject(target);
        context.setVariable("target", target);
        context.setVariable("args", args);
        context.setVariable("method", method);
        context.setVariable("targetClass", targetClass);
        context.setVariable("applicationContext", applicationContext);

        for (Map.Entry<String, Object> entry : applicationContext.getBeansOfType(Object.class).entrySet()) {
            context.setVariable(entry.getKey(), entry.getValue());
        }

        return context;
    }

    public <T> T eval(String expression, AnnotatedElementKey methodKey, EvaluationContext evalContext, Class<T> valueType) {
        Expression expr = PARSER.parseExpression(expression);
        return expr.getValue(evalContext, valueType);
    }
}
